const fs = require('fs');
const path = require('path');
const promisify = require('util').promisify;

const writeFile = promisify(fs.writeFile);
const readFile = promisify(fs.readFile);
const readDir = promisify(fs.readdir);
const getStat = promisify(fs.stat);
const exist = promisify(fs.exists);
const rm = promisify(fs.unlink);

//扫描文件内容，判断结尾字节是否是0x0A
async function scanContent(file_name){
    try {
        let ret = 'NG (文件末尾没有LF)';
        let data = await readFile(file_name);
        if(data.length != 0){
            //判断结尾最后一个字节是否为0x0A(LF)
            if(data[data.length - 1] == 10){
                ret = 'OK (文件末尾有LF)';
            }
        }else{
            ret = 'NG (文件为空)';
        }
        return ret;
    } catch (error) {
        throw new Error('scanContent' + ' : ' + error);
    }
}

//判断文件类型
async function judgeFileType(file_name){
    try {
        let info = await getStat(file_name);
        if(info.isDirectory()){
            //判断当前文件类型是否是路径
            return 'dir';
        }else if(info.isFile()){
            //判断当前文件类型是否是文件
            return 'file';
        }
    } catch (error) {
        throw new Error('judgeFileType' + ' : ' + error);
    }
    
}

//取得文件扩展名
function getExtname(name){
    let result = path.extname(name).split('.');
    return result[result.length - 1];
}

//扫描用户指定的路径，取得当前路径下所有的文件
async function scanDir(dir_name, log_name){
    try {
        let log_data = '';
        let info = await readDir(dir_name);
        //如果指定路径下不是空
        if(info.length != 0){
            // console.log(info);
            //遍历当前路径下的所有文件
            for(let i=0;i<=info.length-1;i++){
                //判断遍历文件的类型
                let sub_path = path.join(dir_name,info[i]);
                // console.log('sub_path : ' + sub_path);
                let type = await judgeFileType(sub_path);
                if(type == 'dir'){
                    //如果是路径的话，则递归调用
                    await scanDir(sub_path, log_name);
                }else if(type == 'file'){
                    //如果是文件的话，则取文件的扩展名
                    let ext = getExtname(sub_path);
                    if(ext == 'htm'){
                        //当前的文件是html的话，则扫描文件内容。
                        //判断最后一个字节是否是0x0A
                        let scan_ret = await scanContent(sub_path);
                        log_data = sub_path + ' : '+ scan_ret;
                    }else{
                        log_data = sub_path + ' : 检测对象外';
                    }
                    await writeScanLog(log_name, log_data);
                }
            }
        }else{
            //如果没有任何文件的话，则记录该路径下没有任何文件
            //console.log(dir_name + ' : ' +'该路径下没有任何文件');
            log_data = dir_name + ' : ' +'该路径下没有任何文件';
            await writeScanLog(log_name, log_data);
        }
    } catch (error) {
        throw new Error('scanDir' + ' : ' + error);
    }
}

//删除扫描结果记录文件
async function deleteScanLog(name){
    try {
        let isExist = await exist(name);
        console.log(isExist);
        if(isExist){
            await rm(name);
        }
    } catch (error) {
        throw new Error('deleteScanLog' + ' : ' + error);
    }
}

//向扫描结果记录文件中记入扫描结果
async function writeScanLog(name, data){
    if(data.length != 0){
        try {
            await writeFile(name, data + '\n', {'flag':'a'});
        } catch (error) {
            throw new Error('writeScanLog' + ' : ' + error);
        }
    }else{
        throw new Error('writeScanLog' + ' : ' + '没有设定写入LOG的内容，暂停执行，请检查程序');
    }
}

//入口
async function run(name){
    try {
        let log_path = path.join(__dirname, 'scan_log.txt')
        await deleteScanLog(log_path);
        await scanDir(name, log_path);
    } catch (error) {
        console.log(error);
    }
}

run('./');